import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {
  Button,
  Card,
  Divider,
  Dropdown,
  Input,
  List,
  Menu,
  message,
  Result,
  Space,
  Spin,
  Tag,
  Typography,
} from 'antd';
import {useSearchParams} from 'react-router-dom';
import style from './Search.module.scss';
import {DownOutlined, ReloadOutlined} from '@ant-design/icons';
import {getSortMethodText, processSpider} from '../../utils/convert';
import {getBooks, getKeys, getSpidersByKey} from '../../network/requests';
import {SpiderInfo} from '../../components/SpiderInfo';
import {CreateSpider} from '../../components/CreateSpider';
import {SpiderHeader} from '../../components/SpiderHeader';
import {BookDetail} from '../../components/BookDetail';


function Search() {
  const suggestions =
    [{key: '计算机网络', id: 1}, {key: '操作系统', id: 2}, {key: '数据库', id: 3}];
  const [keys, setKeys] = useState([]);
  const [searchParams, setSearchParams] = useSearchParams({});
  const [searchContent, setSearchContent] = useState('');
  const [total, setTotal] = useState(0);
  const [searchItems, setSearchItems] = useState([]);
  const [loading, setLoading] = useState(false);
  const [loadingSpiders, setLoadingSpiders] = useState(false);
  const [spiders, setSpiders] = useState({});
  const [page, setPage] = useState(1);
  const [noResult, setNoResult] = useState(false);
  const [createSpiderVisible, setCreateSpiderVisible] = useState(false);
  const [createSpiderKey, setCreateSpiderKey] = useState('');

  const [spiderCollapsed, setSpiderCollapsed] = useState(false);
  const [sortMethod, setSortMethod] = useState('idx');
  const [desc, setDesc] = useState(false);

  const searchBooks = useCallback((j, page) => {
    const jdId = j.jd_spider?.id;
    const ddId = j.dd_spider?.id;
    if (jdId === undefined && ddId === undefined) {
      message.error('未指定 id');
      return;
    }
    setLoading(true);
    getBooks(jdId, ddId, page, sortMethod, desc).then((data) => {
      setTotal(data.total);
      setSearchItems(data.data);
      setLoading(false);
      setPage(data.current_page);
    }).catch(() => {
      message.error('获取图书信息失败');
    });
  }, [sortMethod, desc]);

  useEffect(() => {
    const jdId = spiders.jd_spider?.id;
    const ddId = spiders.dd_spider?.id;
    if (jdId === undefined && ddId === undefined) {
      setSearchItems([]);
      setTotal(0);
      return;
    }
    searchBooks(spiders);
  }, [searchBooks, spiders]);

  useEffect(() => {
    const q = searchParams.get('query');
    if (q) {
      searchSpiders(q);
      setSearchContent(q);
    }
    getKeys().then((keys) => {
      setKeys(keys);
    });
  }, []);

  const searchSpiders = useCallback((key) => {
    if (!key) {
      message.error('请输入关键词');
      return;
    }
    setSearchParams({
      query: key,
    });
    setLoadingSpiders(true);
    setNoResult(false);
    getSpidersByKey(key).then((j) => {
      setSpiders(j);
      setLoadingSpiders(false);
      if (!j.jd_spider && !j.dd_spider) {
        setNoResult(true);
      }
    }).catch(() => {
      setLoadingSpiders(false);
      message.error('获取爬虫信息失败');
      // console.log(err);
    });
  }, [searchBooks, setSearchParams]);

  const [nowDate, setNowDate] = useState(new Date());

  useEffect(() => {
    setInterval(() => {
      setNowDate(new Date());
    }, 1000);
  }, []);

  const parsedSpiders = useMemo(() => ({
    dd_spider: processSpider(spiders.dd_spider),
    jd_spider: processSpider(spiders.jd_spider),
  }), [spiders]);

  const menu = (
    <Menu>
      {
        Object.entries(getSortMethodText).map(([key, value]) => {
          return <Menu.Item
            onClick={() => setSortMethod(key)}
            key={key}>
            {value}
          </Menu.Item>;
        })
      }
    </Menu>
  );

  const descMenu = (
    <Menu>
      <Menu.Item
        key={'asc'}
        onClick={() => setDesc(false)}
      >升序</Menu.Item>
      <Menu.Item
        key={'desc'}
        onClick={() => setDesc(true)}
      >降序</Menu.Item>
    </Menu>
  );

  return (
    <>
      <Space style={{width: '100%'}} direction={'vertical'}>
        <Input.Search
          enterButton="检索数据库"
          size={'large'}
          placeholder={'请输入关键词'}
          value={searchContent}
          onChange={(e) => {
            setSearchContent(e.target.value);
          }}
          onSearch={searchSpiders}
          loading={loadingSpiders}
        />
        <Typography.Paragraph>
          <Typography.Text type={'secondary'}>
            搜索建议：
          </Typography.Text>
          {
            (keys.length ? keys : suggestions).map(({key, id}) =>
              <Tag onClick={() => {
                setSearchContent(key);
                searchSpiders(key);
              }} key={id} className={style.tag}>{key}
              </Tag>)
          }
        </Typography.Paragraph>
      </Space>
      {
        (parsedSpiders.jd_spider || parsedSpiders.dd_spider) &&
        <Spin
          spinning={loadingSpiders}
        >
          <Divider>搜索结果
            <Button
              type={'link'}
              onClick={() => {
                setSpiderCollapsed(!spiderCollapsed);
              }}
            >{spiderCollapsed ? '展开' : '收起'}
            </Button>
          </Divider>
          {
            [parsedSpiders.jd_spider, parsedSpiders.dd_spider].map((spider) => (
              spider && <Card
                key={spider.id}
                title={<SpiderHeader showWarning={true} spider={spider}/>}
                bordered={false}
                className={spiderCollapsed ? style.collapsed : style.spider}
              >
                <List.Item
                  style={{padding: 0}}
                  actions={[
                    <Button
                      key={4}
                      onClick={() => {
                        setCreateSpiderKey(spider.key);
                        setCreateSpiderVisible(true);
                      }}
                      className={style.action}
                      size={'small'} type={'link'}
                      icon={<ReloadOutlined/>}>重新索引
                    </Button>]
                  }
                >
                  <SpiderInfo
                    parsedSpider={spider}
                    nowDate={nowDate}
                  />
                </List.Item>
              </Card>
            ))
          }
        </Spin>
      }
      {
        noResult ?
          <Result status="404"
            title="还未建立索引"
            subTitle={'关键词 ' + searchContent + ' 还没有建立索引，可以立即创建'}
            extra={
              <Button
                onClick={
                  () => {
                    setCreateSpiderKey(searchContent);
                    setCreateSpiderVisible(true);
                  }
                } type="primary">开始爬取</Button>
            }
          /> :
          <>
            <Divider>
              爬取结果
              <Divider type={'vertical'}/>
              <Dropdown trigger={['click']} overlay={menu}>
                <Button
                  type={'link'}
                >
                  {getSortMethodText[sortMethod]} <DownOutlined/>
                </Button>
              </Dropdown>
              <Dropdown trigger={['click']} overlay={descMenu}>
                <Button
                  type={'link'}
                >
                  {desc ? '降序' : '升序'} <DownOutlined/>
                </Button>
              </Dropdown>
            </Divider>
            <List
              loading={loading}
              itemLayout="vertical"
              size="large"
              pagination={{
                onChange: (page) => {
                  searchBooks(spiders, page);
                  setPage(page);
                },
                pageSize: 15,
                total: total,
                position: 'bottom',
                showSizeChanger: false,
                disabled: loading,
                current: page,
              }}
              dataSource={searchItems}
              rowKey={'id'}
              renderItem={(item) => <BookDetail book={item}/>}
            />
          </>
      }
      <CreateSpider
        visible={createSpiderVisible}
        initKey={createSpiderKey}
        callback={(created, key) => {
          setCreateSpiderVisible(false);
          if (created) {
            searchSpiders(key);
          }
        }}
      />
    </>
  );
}

export default Search;
